package com.vchello.service.impl.project;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.vchello.bean.bind.ProjectQuery;
import com.vchello.bean.file.File;
import com.vchello.bean.file.Folder;
import com.vchello.bean.pro.InvestNote;
import com.vchello.bean.pro.Pro;
import com.vchello.bean.pro.ProFollow;
import com.vchello.bean.pro.ProLables;
import com.vchello.bean.pro.ProMilepost;
import com.vchello.bean.pro.ProOrganization;
import com.vchello.bean.pro.ProjectChange;
import com.vchello.bean.user.Invitation;
import com.vchello.bean.user.User;
import com.vchello.bean.user.UserArea;
import com.vchello.bean.user.UserField;
import com.vchello.bean.user.UserProgress;
import com.vchello.dao.file.FileDao;
import com.vchello.dao.file.FolderDao;
import com.vchello.dao.project.InvestNoteDao;
import com.vchello.dao.project.ProFollowDao;
import com.vchello.dao.project.ProLabelDao;
import com.vchello.dao.project.ProMilepostDao;
import com.vchello.dao.project.ProOrganizationDao;
import com.vchello.dao.project.ProjectChangeDao;
import com.vchello.dao.project.ProjectDao;
import com.vchello.dao.user.InvitationDao;
import com.vchello.dao.user.UserAreaDao;
import com.vchello.dao.user.UserDao;
import com.vchello.dao.user.UserFieldDao;
import com.vchello.dao.user.UserProgressDao;
import com.vchello.resulthandler.MapToObjectHandler;
import com.vchello.service.project.ProjectService;
import com.vchello.util.Utility;

@Service(value = "projectService")
public class ProjectServiceImpl extends ServiceImpl<ProjectDao, Pro> implements ProjectService{

	@Autowired
	private ProjectDao projectDao;
	@Autowired
	private UserProgressDao userProgressDao;
	@Autowired
	private ProFollowDao proFollowDao;
	@Autowired
	private ProLabelDao proLabelDao;
	@Autowired
	private ProMilepostDao proMilepostDao;
	@Autowired
	private ProOrganizationDao proOrganizationDao;
	@Autowired
	private InvitationDao invitationDao;
	@Autowired
	private InvestNoteDao investNoteDao;
	@Autowired
	private UserAreaDao userAreaDao;
	@Autowired
	private UserFieldDao userFieldDao;
	@Autowired
	private FolderDao folderDao;
	@Autowired
	private FileDao fileDao;
	@Autowired
	private ProjectChangeDao projectChangeDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private MybatisSqlSessionFactoryBean sqlSessionFactory;

	@Override
	public boolean deleteProject(int id) {
		Pro pro = projectDao.selectById(id);
		//删除项目（团队，跟进人，里程碑，文件夹, 文件， 项目改变记录表）
		System.out.println();
		Wrapper<ProOrganization> wrapper1 = new EntityWrapper<>();
		wrapper1.eq("proId", id);
		List<ProOrganization> proOrganizationList = proOrganizationDao.selectList(wrapper1);
		proOrganizationDao.deleteBatchIds(proOrganizationList);

		Wrapper<ProFollow> wrapper2 = new EntityWrapper<>();
		wrapper2.eq("proId", id);
		List<ProFollow> proFollowList = proFollowDao.selectList(wrapper2);
		proFollowDao.deleteBatchIds(proFollowList);
		
		Wrapper<ProMilepost> wrapper3 = new EntityWrapper<>();
		wrapper3.eq("proId", id);
		List<ProMilepost> proMilepost = proMilepostDao.selectList(wrapper3);
		proMilepostDao.deleteBatchIds(proMilepost);
		
		ProjectChange projectChange = projectChangeDao.findProjectChangeByProId(id);
		if(projectChange!=null){
			projectChangeDao.deleteById(projectChange);
		}
		
		Folder folder1 = folderDao.findByProjectIdAndParentIdAndUserId(pro.getId(), folderDao.findProjectInvestigateFoldByUserId(pro.getUserId()).getId(), pro.getUserId());
		if(folder1!=null){
			List<File> files = folder1.getFileList();
			if(fileDao.deleteBatchIds(files)>0){
				folderDao.deleteById(folder1);
			}
		}
		
		Folder folder = folderDao.findByProjectIdAndParentIdAndUserId(pro.getId(), folderDao.findProjectFolder(pro.getUserId()).getId(), pro.getUserId());
		if(folder!=null){
			List<File> files = folder.getFileList();
			if(fileDao.deleteBatchIds(files)>0){
				folderDao.deleteById(folder);
			}
		}
		return projectDao.deleteById(pro)>0;
	}

	@Override
	public List<Object[]> statisProgress(List<UserProgress> progressList,  int userId) {
		List<Object[]> result = new ArrayList<Object[]>();
		Object[] notDeal = new Object[]{0, "未处理" ,projectDao.statisProgressNotDeal(userId)};
		result.add(notDeal);
		if(progressList.size()>0){
			for(UserProgress up : progressList){
				Object[] obj = new Object[]{up.getId(), up.getName() ,projectDao.statisProgress(up.getId())};
				result.add(obj);
			}
		}
		return result;
	}

	@Override
	public List<Object[]> statisProgressV2(List<UserProgress> progressList, int userId) {
		List<Object[]> result = new ArrayList<Object[]>();
		if(progressList.size()>0){
			for(UserProgress up : progressList){
				Object[] obj = new Object[]{up ,projectDao.statisProgress(up.getId())};
				result.add(obj);
			}
		}
		return result;
	}

	@Override
	public Page<Pro> queryPage(Page<Pro> page, ProjectQuery query) {
		Wrapper<Pro> wrapper = new EntityWrapper<Pro>();
		if(query.getAreaId()!=0){
			wrapper.eq("areaId", query.getAreaId());
		}
		if(query.getFieldId()!=0){
			wrapper.eq("fieldId", query.getFieldId());
		}
		if(query.getRoundId()!=0){
			wrapper.eq("roundId", query.getRoundId());
		}
		if(query.getUnitId()!=0){
			wrapper.eq("unit", query.getUnitId());
		}
/*		if (ToolUtil.isNotEmpty(query.getCondition())) {
			Disjunction disjunction = Restrictions.disjunction();
			DetachedCriteria dcUser = dc.createAlias("user", "user");
			dc.add(Restrictions.or(Restrictions.like("user.userName", query.getCondition(),MatchMode.ANYWHERE), Restrictions.like("name", query.getCondition(),MatchMode.ANYWHERE)));
			dcUser.add(disjunction);
		}*/
		if(query.getUserType()==1){
			wrapper.eq("userId", query.getUserId());
			if(query.getDealmanId()!=0){
				Object[] dealmans = projectChangeDao.findDealmanIds(query.getDealmanId(), query.getUserId());
				if(dealmans!=null){
					wrapper.in("id", dealmans);
				}else{
					wrapper.in("id", new Object[]{0});
				}
			}
		}
/*		if (query.getUserType()==2) {
			Object[] proIds = projectChangeDao.findIdsByUserId(query.getUserId());
			if(proIds!=null){
				wrapper.or(sqlOr, params)
				dc.add(Restrictions.or(Restrictions.in("id", proIds),Restrictions.eq("userId", query.getUserId())));
			}else{
				wrapper.eq("userId", query.getUserId());
			}
		}*/
		if(query.getProgressId()!=0){
			wrapper.eq("progressId", query.getProgressId());
		}
		
/*		if(query.getKeyWorld()!=null&&query.getKeyWorld()!=""){
			//搜索团队信息
			Object[] ids = proOrganizationDao.queryByKeyWorld(query.getKeyWorld().trim());
			if(ids!=null){
				dc.add(Restrictions.or(Restrictions.in("id", ids),Restrictions.like("name", query.getKeyWorld().trim(), MatchMode.ANYWHERE)));
			}else{
				dc.add(Restrictions.like("name", query.getKeyWorld().trim(), MatchMode.ANYWHERE));
			}
		}*/
		return selectPage(page, wrapper);
	}

	@Override
	public long allDataCount(int userId) {
		Wrapper<Pro> wrapper = new EntityWrapper<>();
		wrapper.eq("userId", userId);
		return projectDao.selectCount(wrapper);
	}

	@Override
	public Long allDataCounForInvestor(int userId) {
		//先查询个人部分
		Wrapper<Pro> wrapper1 = new EntityWrapper<>();
		wrapper1.eq("user_id", userId);
		long personCount = projectDao.selectCount(wrapper1);
		//后查询机构部分
		Wrapper<ProjectChange> wrapper2 = new EntityWrapper<>();
		wrapper2.eq("user_id", userId);
		long parentCount = projectChangeDao.selectCount(wrapper2);
		return personCount+parentCount;
	}

	@Override
	public int queryProgressSort(int userId) {
		return userProgressDao.queryProgressSort(userId)+1;
	}

	@Override
	public boolean saveOrUpdateProgress(UserProgress userProgress) {
		if(userProgress.getId()!=0){
			return userProgressDao.updateById(userProgress)>0;
		}
		return userProgressDao.insert(userProgress)>0;
	}

	@Override
	public UserProgress findUserProgressById(int id) {
		return userProgressDao.selectById(id);
	}

	@Override
	public Pro findProjectById(int id) {
		return projectDao.selectById(id);
	}

	@Override
	public boolean saveOrUpdateProject(Pro pro) {
		if(pro.getId()!=0){
			return projectDao.updateById(pro)>0;
		}
		return projectDao.insert(pro)>0;
	}

	@Override
	public boolean updateFollow(int[] ids, int proId) {
		Wrapper<ProFollow> wrapper = new EntityWrapper<>();
		wrapper.eq("proId", proId);
		List<ProFollow> D_list = proFollowDao.selectList(wrapper);
		for(ProFollow t : D_list){
			proFollowDao.deleteById(t);
		}
		List<ProFollow> I_list = new ArrayList<ProFollow>();
		if(ids!=null&&ids.length>0){
			for(int id : ids){
				proFollowDao.insert(new ProFollow(id, proId));
			}
			return true;
		}
		return true;
	}

	@Override
	public boolean updatePro(Pro pro) {
		return projectDao.updateById(pro)>0;
	}

	@Override
	public boolean checkPrograss(int prograssId) {
		return projectDao.statisProgress(prograssId)>0?false:true;
	}

	@Override
	public boolean deletePrograss(int prograssId) {
		return userProgressDao.deleteById(prograssId);
	}

	@Override
	public boolean saveOrUpdate(Pro pro) {
		if(pro.getId() != 0){
			projectDao.updateById(pro);
		}else{
			projectDao.insert(pro);
			//处理其他文件
			Folder folder = folderDao.findProjectFolder(pro.getUserId());
			//处理项目文件夹没有创建的时候
			if(folder==null){
				folder = new Folder("项目文件", pro.getUserId(), 0, 0, Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss"));
				folderDao.insert(folder);
			}
			folderDao.insert(new Folder(pro.getName(), pro.getUserId(), pro.getId(), folder.getId(), Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss")));
			
			//处理尽调文件
			Folder investigefolder = folderDao.findProjectInvestigateFoldByUserId(pro.getUserId());
			//处理项目文件夹没有创建的时候
			if(investigefolder==null){
				folder = new Folder("尽调文件", pro.getUserId(), 0, 0, Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss"));
				folderDao.insert(investigefolder);
			}
			folderDao.insert(new Folder(pro.getName(), pro.getUserId(), pro.getId(), investigefolder.getId(), Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss")));
		}
		return true;
	}

	@Override
	public boolean saveProLabels(List<ProLables> list) {
		for(ProLables label : list){
			proLabelDao.insert(label);
		}
		return true;
	}

	@Override
	public boolean deleteProlabels(int projectId) {
		return proLabelDao.deleteFromProId(projectId);
	}

	@Override
	public boolean updateMilepost(List<ProMilepost> list) {
		for(ProMilepost milepost : list){
			if(milepost.getId()!=0){
				boolean flag = proMilepostDao.updateById(milepost)>0;
				if(!flag){
					return false;
				}
			}else{
				boolean flag = proMilepostDao.insert(milepost)>0;
				if(!flag){
					return false;
				}
			}
		}
		return true;
	}

	@Override
	public boolean updateOrganizations(List<ProOrganization> list) {
		for(ProOrganization orgnize : list){
			if(orgnize.getId()!=0){
				boolean flag = proOrganizationDao.updateById(orgnize)>0;
				if(!flag){
					return false;
				}
			}else{
				boolean flag = proOrganizationDao.insert(orgnize)>0;
				if(!flag){
					return false;
				}
			}
		}
		return true;
	}

	@Override
	public List<Invitation> getInvitationList(int userId, String keyWord) {
		return invitationDao.getInvitationByInviteId(userId, keyWord);
	}

	@Override
	public boolean updateFollow(List<ProFollow> follows) {
		if(proFollowDao.deleteFollowByPro(follows.get(0).getProId())){
			for(ProFollow follow : follows){
				proFollowDao.insert(follow);
			}
			return true;
		}
		return false;
	}

	@Override
	public InvestNote saveOrUpdateNote(InvestNote investNote) {
		if(investNote.getId()!=0){
			InvestNote updateBean = investNoteDao.selectById(investNote.getId());
			updateBean.setContent(investNote.getContent());
			updateBean.setUpdateTime(Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss"));
			updateBean.setUserId(investNote.getUserId());
			investNoteDao.updateById(updateBean);
			return updateBean;
		}else{
			investNote.setCreateTime(Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss"));
			investNote.setUpdateTime(Utility.getDateNowFromformatStr("yyyy-MM-dd HH:mm:ss"));
			investNoteDao.insert(investNote);
			return investNote;
		}
	}

	@Override
	public boolean delNote(int id) {
		return investNoteDao.deleteById(id)>0;
	}

	@Override
	public boolean updateAreas(int[] ids, int userId, List<UserArea> dList) {
		for(UserArea ua : dList){
			userAreaDao.deleteById(ua);
		}
		List<UserArea> iList = new ArrayList<>();
		if(ids!=null){
			for(int i=0; i<ids.length; i++){
				userAreaDao.insert(new UserArea(ids[i], i+1, userId));
			}
			return true;
		}
		return false;
	}

	@Override
	public boolean updateFields(int[] ids, int userId, List<UserField> dList) {
		for(UserField ua : dList){
			userFieldDao.deleteById(ua);
		}
		List<UserField> iList = new ArrayList<>();
		if(ids!=null){
			for(int i=0; i<ids.length; i++){
				userFieldDao.insert(new UserField(ids[i], i+1, userId));
			}
			return true;
		}
		return false;
	}

	@Override
	public List<UserArea> findUserArea(int userId) {
		Wrapper<UserArea> wrapper = new EntityWrapper<>();
		wrapper.eq("userId", userId);
		return userAreaDao.selectList(wrapper);
	}

	@Override
	public List<UserField> findUserField(int userId) {
		Wrapper<UserField> wrapper = new EntityWrapper<>();
		wrapper.eq("userId", userId);
		return userFieldDao.selectList(wrapper);
	}

	@Override
	public boolean deleteMilepost(ProMilepost mile) {
		return proMilepostDao.deleteById(mile)>0;
	}

	@Override
	public ProMilepost findProMilepostById(int id) {
		return proMilepostDao.selectById(id);
	}

	@Override
	public boolean deleteOrganiza(ProOrganization mile) {
		return proOrganizationDao.deleteById(mile)>0;
	}

	@Override
	public ProOrganization findProOrganizaById(int id) {
		return proOrganizationDao.selectById(id);
	}

	@Override
	public boolean saveProFollow(ProFollow pf) {
		return proFollowDao.insert(pf)>0;
	}

	@Override
	public List<Object[]> statisOganizeProgress(int userId) {
		List<Object[]> result = new ArrayList<Object[]>();
		List<Map<String, Object>> list = projectChangeDao.statisProgressFromOrganize(userId);
		if(list.size()>0){
			for(Map<String, Object> map : list){
				if(map.get("user_progress_id")!=null){
					Object[] obj = new Object[]{userProgressDao.selectById((int)map.get("user_progress_id")) ,map.get("count")};
					result.add(obj);
				}
			}
		}
		return result;
	}

	@Override
	public List<UserProgress> userProgressesList(int userId) {
		User user = userDao.findUserById(userId);
		Wrapper<Invitation> wrapper = new EntityWrapper<Invitation>();
		wrapper.eq("receive_id", userId).eq("send_status", 2);
		Invitation invtation = invitationDao.selectList(wrapper).get(0);
		
		List<UserProgress> list = null;
		if(user.getUserProgressList()!=null){
			list = new ArrayList<UserProgress>();
			for(UserProgress up : user.getUserProgressList()){
				list.add(up);
			}
		}
		if(invtation!=null){
			User parentUser = userDao.findUserById(invtation.getInviteId());;
			if(parentUser.getUserProgressList()!=null){
				if(list == null){
					list = new ArrayList<UserProgress>();
				}
				for(UserProgress up : parentUser.getUserProgressList()){
					list.add(up);
				}
			}
		}
		return list;
	}

	@Override
	public ProjectChange findProjectChangeByProId(int projectId) {
		return projectChangeDao.findProjectChangeByProId(projectId);
	}

	@Override
	public boolean saveOrUpdateProjectChange(ProjectChange projectChange) {
		boolean flag = false;
		if(projectChange.getId()!=0){
			flag = projectChangeDao.updateById(projectChange)>0;
		}else{
			flag = projectChangeDao.insert(projectChange)>0;
		}
		return flag;
	}

	@Override
	public boolean deleteProjectChange(ProjectChange projectChange) {
		return projectChangeDao.deleteById(projectChange)>0;
	}

	@Override
	public List<ProjectChange> queryProjectChanges(int userId) {
		return projectChangeDao.findProjectChangeByUserid(userId);
	}

	@Override
	public List<Object[]> findHasProgress(int userId) {
		return projectChangeDao.findHasProgress(userId);
	}

	@Override
	public int findProgressIdByForm(int userId, int fromId) {
		return userProgressDao.findProgressIdByForm(userId, fromId);
	}

	@Override
	public boolean deleteProjectChange(List<ProjectChange> list) {
		return projectChangeDao.deleteBatchIds(list)>0;
	}

	@Override
	public List<ProLables> findProLablesByProId(int proId) {
		return proLabelDao.findByProId(proId);
	}

	@Override
	public List<InvestNote> findInvestNoteByProId(int proId) {
		return investNoteDao.findByProId(proId);
	}

	@Override
	public List<ProMilepost> findProMilepostByProId(int proId) {
		return proMilepostDao.findProMilepostByProId(proId);
	}

	@Override
	public List<ProOrganization> findProOrganizationByProId(int proId) {
		return proOrganizationDao.findProOrganizationByProId(proId);
	}

	@Override
	public List<Object[]> findOrganizeProgress(int organizeUserId, int userId) {
		SqlSession sqlSession = null;
		MapToObjectHandler resulthandler = new MapToObjectHandler();
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("organizeUserId", organizeUserId);
		map.put("userId", userId);
		try {
			sqlSession = sqlSessionFactory.getObject().openSession();
			sqlSession.select("findOrganizeProgress", map, resulthandler);
			return resulthandler.getObjectArry();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			sqlSession.close();
		}
		return null;
	}
}
